<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\stat\cdc;

use app\enum\QqEnum;
use app\model\mongo\MongoQqAccountDayReportModel;
use app\service\BaseService;
use app\service\client\AccountService;
use app\service\stat\StatModelInterface;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Model;

class QqAdvertiserCostStatService extends BaseService implements StatModelInterface
{
    /**
     * 获取广告账户流水信息.
     * @param string $advertiserId 账户ID
     * @param int $statDate 日期
     * @param array $params 表参数
     * @return null|array|mixed|Model|MongoQqAccountDayReportModel
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getStatInfo(string $advertiserId = '', int $statDate = 0, array $params = [])
    {
        // $statDate = intval(date('Ymd', $params['time']));
        $where = [
            ['adv_id', '=', $advertiserId],
            ['stat_date', '=', $statDate],
            ['fund_type', '=', $params['fund_type'] ?? ''],
        ];
        return (new MongoQqAccountDayReportModel())->where($where)->find();
    }

    /**
     * 修改报表信息.
     * @param Model $model 表模型
     * @param array $params 表参数
     */
    public static function updateStatData(Model $model, array $params = []): bool
    {
        if (! $model instanceof MongoQqAccountDayReportModel) {
            return self::setError('报表模型错误');
        }
        try {
            // 更新为最新的信息
            $accountInfo = BaseService::getClientAccountInfo($model->getAttr('adv_id'));

            $newParams = self::filterParams($params);
            $balance = floatval($params['balance']);
            $creditModify = floatval($params['credit_modify']);
            $deposit = floatval($params['deposit']);
            $fundType = strval($params['fund_type']);
            $paid = floatval($params['paid']);
            $preauthBalance = floatval($params['preauth_balance']);
            $transIn = floatval($params['trans_in']);
            $transOut = floatval($params['trans_out']);
            $cost = floatval($newParams['cost']);
            $cashCost = floatval($newParams['cash_cost']);

            // 主表
            $insertId = $model->strict(false)->where('_id', strval($model->getAttr('_id')))->save([
                'client_id' => $accountInfo['client_id'] ?? 0,
                'account_id' => $accountInfo['id'] ?? 0,
                'account_type' => $accountInfo['account_type'] ?? 0,
                'balance' => $balance,
                'credit_modify' => $creditModify,
                'deposit' => $deposit,
                'fund_type' => $fundType,
                'paid' => $paid,
                'preauth_balance' => $preauthBalance,
                'trans_in' => $transIn,
                'trans_out' => $transOut,
                'cost' => $cost,
                'cash_cost' => $cashCost,
                'update_time' => time(),
                'content' => $params,
            ]);
            if ($insertId <= 0) {
                return self::setError('修改报表信息失败');
            }
            return true;
        } catch (\Exception $e) {
            return self::setError($e->getMessage());
        }
    }

    /**
     * 修改报表信息.
     * @param Model $model 表模型
     * @param array $params 表参数
     */
    public static function updateReportData(Model $model, array $params = []): bool
    {
        if (! $model instanceof MongoQqAccountDayReportModel) {
            return self::setError('报表模型错误');
        }
        try {
            // 更新为最新的信息
            $accountInfo = BaseService::getClientAccountInfo($model->getAttr('adv_id'));
            $cost = floatval($params['cost'] / 100);

            // 主表
            $insertId = $model->strict(false)->where('_id', strval($model->getAttr('_id')))->save([
                'client_id' => $accountInfo['client_id'] ?? 0,
                'account_id' => $accountInfo['id'] ?? 0,
                'account_type' => $accountInfo['account_type'] ?? 0,
                'cost' => $cost,
                'update_time' => time(),
                'content' => $params,
            ]);
            if ($insertId <= 0) {
                return self::setError('修改报表信息失败');
            }
            return true;
        } catch (\Exception $e) {
            return self::setError($e->getMessage());
        }
    }

    /**
     * 插入报表信息.
     * @param string $advertiserId 账户id
     * @param array $params 表参数
     */
    public static function insertStatData(string $advertiserId = '', array $params = []): bool
    {
        try {
            $accountInfo = BaseService::getClientAccountInfo($advertiserId);
            $newParams = self::filterParams($params);

            $statDate = intval(date('Ymd', $params['time']));
            $statMonth = intval(date('Ym', $params['time']));
            $balance = floatval($params['balance']);
            $creditModify = floatval($params['credit_modify']);
            $deposit = floatval($params['deposit']);
            $fundType = strval($params['fund_type']);
            $paid = floatval($params['paid']);
            $preauthBalance = floatval($params['preauth_balance']);
            $transIn = floatval($params['trans_in']);
            $transOut = floatval($params['trans_out']);
            $cost = floatval($newParams['cost']);
            $cashCost = floatval($newParams['cash_cost']);

            $data = [
                'client_id' => $accountInfo['client_id'] ?? 0,
                'account_id' => $accountInfo['id'] ?? 0,
                'account_type' => $accountInfo['account_type'] ?? 0,
                'product_id' => $accountInfo['product_id'] ?? 0,
                'adv_id' => $advertiserId,
                'stat_date' => $statDate,
                'stat_month' => $statMonth,
                'balance' => $balance,
                'credit_modify' => $creditModify,
                'deposit' => $deposit,
                'fund_type' => $fundType,
                'paid' => $paid,
                'preauth_balance' => $preauthBalance,
                'trans_in' => $transIn,
                'trans_out' => $transOut,
                'project_id' => $accountInfo['project_id'] ?? 0,
                'staff_id' => $accountInfo['staff_id'] ?? 0,
                'cost' => $cost,
                'cash_cost' => $cashCost,
                'is_sync' => MongoQqAccountDayReportModel::SYNC_FAIL,
                'create_time' => time(),
                'update_time' => time(),
                'content' => $params,
            ];
            $model = new MongoQqAccountDayReportModel();
            $id = $model->insertGetId($data);

            if ($id <= 0) {
                return self::setError('插入报表信息失败');
            }
            return true;
        } catch (\Exception $e) {
            return self::setError($e->getMessage());
        }
    }

    /**
     * 插入报表信息.
     * @param string $advertiserId 账户id
     * @param array $params 表参数
     */
    public static function insertReportData(string $advertiserId = '', array $params = []): bool
    {
        try {
            $accountInfo = BaseService::getClientAccountInfo($advertiserId);
            $statDate = intval(date('Ymd', strtotime($params['date'])));
            $statMonth = intval(date('Ym', strtotime($params['date'])));
            $balance = 0;
            $creditModify = 0;
            $deposit = 0;
            $fundType = '';
            $paid = 0;
            $preauthBalance = 0;
            $transIn = 0;
            $transOut = 0;
            $cost = floatval($params['cost'] / 100);
            $cashCost = 0;

            $data = [
                'client_id' => $accountInfo['client_id'] ?? 0,
                'account_id' => $accountInfo['id'] ?? 0,
                'adv_id' => $advertiserId,
                'account_type' => $accountInfo['account_type'] ?? 0,
                'product_id' => $accountInfo['product_id'] ?? 0,
                'stat_date' => $statDate,
                'stat_month' => $statMonth,
                'balance' => $balance,
                'credit_modify' => $creditModify,
                'deposit' => $deposit,
                'fund_type' => $fundType,
                'paid' => $paid,
                'preauth_balance' => $preauthBalance,
                'trans_in' => $transIn,
                'trans_out' => $transOut,
                'project_id' => $accountInfo['project_id'] ?? 0,
                'staff_id' => $accountInfo['staff_id'] ?? 0,
                'cost' => $cost,
                'cash_cost' => $cashCost,
                'is_sync' => MongoQqAccountDayReportModel::SYNC_FAIL,
                'source' => MongoQqAccountDayReportModel::SOURCE_REPORT,
                'create_time' => time(),
                'update_time' => time(),
                'content' => $params,
            ];
            $model = new MongoQqAccountDayReportModel();
            $id = $model->insertGetId($data);

            if ($id <= 0) {
                return self::setError('插入报表信息失败');
            }
            return true;
        } catch (\Exception $e) {
            return self::setError($e->getMessage());
        }
    }

    /**
     * 对比数据是否相同.
     * @param Model $model 表模型
     * @param array $param 表参数
     * @param array $source 来源
     */
    public static function isSame(Model $model, array $param = []): bool
    {
        $difField = [
            'deposit', 'paid', 'trans_in', 'trans_out', 'credit_modify', 'balance', 'preauth_balance',
        ];

        // 验证数据是否相同
        foreach ($difField as $val) {
            if ($model->getAttr($val) != $param[$val]) {
                return false;
            }
        }

        // 判断账户是否已更新
        $accountInfo = AccountService::getAccountModel(0, strval($param['account_id']));
        if ($accountInfo->getAttr('client_id') != $model->getAttr('client_id') || $accountInfo->getAttr('id') != $model->getAttr('account_id')) {
            return false;
        }
        return true;
    }

    /**
     * 过滤消耗数据.
     * @param array $data 接口数据
     */
    private static function filterParams(array $data = []): array
    {
        if ($data) {
            $paid = $data['paid'] / 100;
            $data['cost'] = 0;
            $data['cash_cost'] = 0;
            if ($data['fund_type'] == QqEnum::FUND_TYPE_VIRTUAL || $data['fund_type'] == QqEnum::FUND_TYPE_SPECIAL_GIFT) {
                $data['cost'] += $paid;
            } else {
                $data['cost'] += $paid;
                $data['cash_cost'] += $paid;
            }
            //            if ($data['fund_type'] == QqEnum::FUND_TYPE_CASH) {// 现金消耗
            //                $data['cost'] += $paid;
            //                $data['cash_cost'] += $paid;
            //            } elseif ($data['fund_type'] == QqEnum::FUND_TYPE_VIRTUAL) {// 补偿虚拟金消耗
            //                $data['cost'] += $paid;
            //            } elseif ($data['fund_type'] == QqEnum::FUND_TYPE_ROLL) {// 固定信用金消耗
            //                $data['cost'] += $paid;
            //                $data['cash_cost'] += $paid;
            //            }
        }
        return $data;
    }
}
